//==================================================================
//  Copyright (C) 2006-2007  Davide Pasca
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//==================================================================
///
///
///
///
///
//==================================================================

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <windows.h>
#include <gl/glew.h>
#include "psys.h"
#include "pwindow.h"
#include "font.h"
#include "menu.h"
#include "gfxutils.h"

//==================================================================
#define CHECK_WIDTH		16
#define X1_MARGIN		2
#define X2_MARGIN		2
#define CHECK_X_MARGIN	2

#define Y1_MARGIN		2
#define Y2_MARGIN		2

//==================================================================
void MenuItem::baseInit()
{
	_userdatap = NULL;
	_radiolistp = NULL;
	_radio_idx = 0;
	_flags = 0;
	_y = 0;
	_width = 0;
	_h = 0;
	_selected = false;
	_submenup = NULL;
}

//==================================================================
MenuItem::MenuItem( MenuUserDataPtr userdatap, MenuItem::Type type, const TCHAR *namep )
{
	baseInit();

	_userdatap = userdatap;
	_type = type;
	_tcscpy_s( _name, namep );

}

//==================================================================
MenuItem::MenuItem( const TCHAR *namep, Menu *submenup )
{
	baseInit();

	_type = TYPE_SUBMENU;
	_submenup = submenup;
	_tcscpy_s( _name, namep );
}

//==================================================================
MenuItem::MenuItem( RadioList *radiolistp, const TCHAR *namep )
{
	baseInit();

	_userdatap = radiolistp->_userdatap;
	_type = TYPE_RADIOLIST_ITEM;
	_radiolistp = radiolistp;
	_tcscpy_s( _name, namep );
}

//==================================================================
MenuItem::MenuItem( bool *toggle_valp, const TCHAR *namep )
{
	baseInit();

	_userdatap = toggle_valp;
	_type = TYPE_TOGGLE_ITEM;
	_tcscpy_s( _name, namep );
}

//==================================================================
MenuItem::~MenuItem()
{
	if ( _type == TYPE_RADIOLIST_ITEM )
		_radiolistp->SubRef();
}

//==================================================================
void MenuItem::SetCheck( bool onoff )
{
	switch( _type )
	{
	case TYPE_CHECK:
		*((bool *)_userdatap) = onoff;
		break;

	case TYPE_TOGGLE_ITEM:
		*((bool *)_userdatap) = onoff;
		break;

	case TYPE_RADIOLIST_ITEM:
		PASSERT( onoff == true );
		_radiolistp->SetSelIdx( _radio_idx );
		break;

	case TYPE_TITLE:
	case TYPE_EMPTY:
	case TYPE_SUBMENU:
	default:
		PASSERT( 0 );
		break;
	}
}

//==================================================================
bool MenuItem::GetCheck() const
{
	switch( _type )
	{
	case TYPE_CHECK:
		return *((bool *)_userdatap);

	case TYPE_TOGGLE_ITEM:
		return *((bool *)_userdatap);

	case TYPE_RADIOLIST_ITEM:
		return _radiolistp->GetSelIdx() == _radio_idx;

	case TYPE_TITLE:
	case TYPE_EMPTY:
	case TYPE_SUBMENU:
	default:
		PASSERT( 0 );
		return false;
	}
}

//==================================================================
bool MenuItem::Toggle()
{
	bool	flipped = !GetCheck();

	SetCheck( flipped );

	return flipped;
}

//==================================================================
//==================================================================
Menu::Menu() :
	_visible(false),
	_active(true),
	_is_popup(true),
	_flags(0),
	_disp_w(0),
	_disp_h(0),
	_activity_childp(NULL),
	_x(0),
	_y(0),
	_w(0),
	_h(0),
	_last_mouse_offset_x(-8),
	_last_mouse_offset_y(-8),
	_cur_sel_item(0),
	_lbutt_down_sel_item(-1),
	_callback(NULL),
	_callback_userdatap(NULL)
{
}

//==================================================================
void Menu::Reset()
{
	for (int i=0; i < _itemsp.size(); ++i)
		delete _itemsp[i];

	_itemsp.clear();

	invalidate();
}

//==================================================================
void Menu::AddNormalItem( MenuUserDataPtr userdatap, const TCHAR *namep )
{
	addItem( userdatap, MenuItem::TYPE_NORMAL, namep );
}
//==================================================================
void Menu::AddTitleItem( MenuUserDataPtr userdatap, const TCHAR *namep )
{
	addItem( userdatap, MenuItem::TYPE_TITLE,namep );
}
//==================================================================
void Menu::AddEmptyItem( MenuUserDataPtr userdatap, const TCHAR *namep )
{
	addItem( userdatap, MenuItem::TYPE_EMPTY, namep );
}
//==================================================================
void Menu::AddCheckItem( bool *userdatap, const TCHAR *namep )
{
	PASSERT( userdatap != NULL );
	addItem( userdatap, MenuItem::TYPE_CHECK, namep );
	ItemSetCheck( userdatap, *userdatap );
}
//==================================================================
void Menu::AddToggleItem( bool *userdatap, const TCHAR *namep )
{
	PASSERT( userdatap != NULL );
	addItem( userdatap, MenuItem::TYPE_TOGGLE_ITEM, namep );
	ItemSetCheck( userdatap, *userdatap );
}

//==================================================================
void Menu::addItem( MenuUserDataPtr userdatap, MenuItem::Type type, const TCHAR *namep )
{
	MenuItem	*new_itemp = new MenuItem( userdatap, type, namep );

	_itemsp.push_back( new_itemp );	// throws
	recalcGeometry();
	invalidate();
}

//==================================================================
void Menu::addItem( RadioList *radiolistp, const TCHAR *namep )
{
	MenuItem	*new_itemp = new MenuItem( radiolistp, namep );

	new_itemp->_radio_idx = _itemsp.size();

	_itemsp.push_back( new_itemp );	// throws
	recalcGeometry();
	invalidate();
}

//==================================================================
void Menu::AddSubmenu( const TCHAR *namep, class Menu *submenup )
{
	MenuItem	*new_itemp = new MenuItem( namep, submenup );
	
	_itemsp.push_back( new_itemp );
	recalcGeometry();
	invalidate();
}

//==================================================================
void Menu::RemoveItem( MenuUserDataPtr userdatap )
{
	int	i = find_item_by_id( userdatap );
	if PBADPATH( i < 0 )
		return;

	delete _itemsp[i];
	
	_itemsp.erase( _itemsp.begin() + i );
	recalcGeometry();
	invalidate();
}

//==================================================================
int Menu::find_item_by_id( MenuUserDataPtr userdatap ) const
{
	for (int i=0; i < _itemsp.size(); ++i)
	{
		if ( _itemsp[ i ]->_userdatap == userdatap )
			return i;
	}
	return -1;
}

//==================================================================
void Menu::SetItemText( MenuUserDataPtr userdatap, const TCHAR *textp )
{
	int	i = find_item_by_id( userdatap );
	if PBADPATH( i < 0 )
		return;

	_itemsp[i]->SetName( textp );
	recalcGeometry();
	invalidate();
}

//==================================================================
void Menu::ItemSetCheck( MenuUserDataPtr userdatap, bool onoff )
{
	int	i = find_item_by_id( userdatap );
	if ( i < 0 )
		return;

	_itemsp[ i ]->SetCheck( onoff );
	invalidate();
}
//==================================================================
bool Menu::ItemGetCheck( MenuUserDataPtr userdatap ) const
{
	int	i = find_item_by_id( userdatap );
	if ( i < 0 )
		return false;

	return _itemsp[ i ]->GetCheck();
}
//==================================================================
bool Menu::ItemToggleCheck( MenuUserDataPtr userdatap )
{
	int	i = find_item_by_id( userdatap );
	if ( i < 0 )
		return false;

	invalidate();

	return _itemsp[ i ]->Toggle();
}
/*
//==================================================================
bool Menu::ItemSetCheckExclusive( MenuUserDataPtr userdatap, bool *list[] )
{
	for (int i=0; list[i] != NULL; ++i)
	{
		if ( userdatap == list[i] )
		{
			for (int j=0; list[j] != NULL; ++j)
			{
				*list[j] = ( userdatap == list[j] );
				ItemSetCheck( list[j] );
			}
			
			return true;
		}
	}

	return false;
}
*/
//==================================================================
void Menu::SetPos( int x, int y )
{
	_x = x;
	_y = y;

	invalidate();
}

//==================================================================
void Menu::Show( bool onoff )
{
	if ( onoff != _visible )
	{
		_visible = onoff;
		_cur_sel_item = -1;	// invalidate the currently selected item
		_lbutt_down_sel_item = -1;
	}

	invalidate();
}

//==================================================================
void Menu::SetPopup( bool onoff )
{
	_is_popup = onoff;
}

//==================================================================
void Menu::recalcGeometry()
{
	int	y = 0;

	_w = 32;

	for (int i=0; i < _itemsp.size(); ++i)
	{
		int	w = X1_MARGIN + FONT_StringWidth( _itemsp[i]->_name ) + X2_MARGIN;
		//if ( item._type == MenuItem::TYPE_CHECK )
		{
			w += CHECK_WIDTH + CHECK_X_MARGIN;
		}
		if ( w > _w )
			_w = w;

		int	h = Y1_MARGIN + FONT_TextHeight() + Y2_MARGIN;

		_itemsp[i]->_y = y;
		_itemsp[i]->_h = h;

		y += h;
	}
	
	_h = y;
}

//==================================================================
static void draw_fan( float cx, float cy, float radius, float ang_start, float ang_end, float in_alpha )
{
	ang_start *= 3.14159265 / 180;
	ang_end *= 3.14159265 / 180;

	float	ang_step = (ang_end - ang_start) / 4;

	glBegin( GL_TRIANGLE_FAN );

		glColor4f( 0, 0, 0, in_alpha );
		glVertex2f( cx, cy );

		glColor4f( 0, 0, 0, 0 );
		for (int i=0; i <= 4; ++i)
		{
			float	co = cos( ang_start + i * ang_step );
			float	si = sin( ang_start + i * ang_step );

			glVertex2f( cx + radius * co, cy - radius * si );
		}

	glEnd();
}

//==================================================================
static void draw_round_box( float x, float y, float w, float h, float radius, float in_alpha )
{
	float	x1 = x;
	float	y1 = y;
	float	x2 = x+w;
	float	y2 = y+h;

	float	x1in = x + radius;
	float	y1in = y + radius;
	float	x2in = x+w - radius;
	float	y2in = y+h - radius;

	glColor4f( 0, 0, 0, in_alpha );
	glBegin( GL_TRIANGLE_STRIP );
		glVertex2f( x1in, y1in );
		glVertex2f( x2in, y1in );
		glVertex2f( x1in, y2in );
		glVertex2f( x2in, y2in );
	glEnd();

	// Left
	glBegin( GL_QUADS );
		glColor4f( 0, 0, 0, 0.0f );
		glVertex2f( x1, y1in );
		
		glColor4f( 0, 0, 0, in_alpha );
		glVertex2f( x1in, y1in );
		glVertex2f( x1in, y2in );

		glColor4f( 0, 0, 0, 0.0f );
		glVertex2f( x1, y2in );
//	glEnd();

	// Right
//	glBegin( GL_TRIANGLE_STRIP );
		glColor4f( 0, 0, 0, in_alpha );
		glVertex2f( x2in, y1in );

		glColor4f( 0, 0, 0, 0.0f );
		glVertex2f( x2, y1in );
		glVertex2f( x2, y2in );

		glColor4f( 0, 0, 0, in_alpha );
		glVertex2f( x2in, y2in );
	glEnd();

	// Top
	glBegin( GL_TRIANGLE_STRIP );
		glColor4f( 0, 0, 0, 0.0f );
		glVertex2f( x1in, y1 );
		glVertex2f( x2in, y1 );

		glColor4f( 0, 0, 0, in_alpha );
		glVertex2f( x1in, y1in );
		glVertex2f( x2in, y1in );
	glEnd();

	// Bottom
	glBegin( GL_TRIANGLE_STRIP );
		glColor4f( 0, 0, 0, in_alpha );
		glVertex2f( x1in, y2in );
		glVertex2f( x2in, y2in );

		glColor4f( 0, 0, 0, 0.0f );
		glVertex2f( x1in, y2 );
		glVertex2f( x2in, y2 );
	glEnd();

	draw_fan( x1in, y1in, radius, 180,	90,	in_alpha );
	draw_fan( x2in, y1in, radius, 90,	0,	in_alpha );
	draw_fan( x1in, y2in, radius, 180,	270,in_alpha );
	draw_fan( x2in, y2in, radius, 270,	360,in_alpha );
}

//==================================================================
static void draw_shadow_box( int x, int y, int w, int h )
{
	glEnable( GL_BLEND );
	glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

	draw_round_box( x, y, w, h, 16, 0.4f );
}

//==================================================================
void Menu::redrawSub()
{
	if NOT( _visible )
		return;

	glLoadIdentity();

	draw_shadow_box( _x-10, _y-2, _w+20, _h+16 );

	int y = _y;
	for (int i=0; i < _itemsp.size(); ++i)
	{
		const MenuItem	&item = *_itemsp[ i ];

		glLoadIdentity();
		glTranslatef( _x, _y + item._y, 0 );

		glBegin( GL_TRIANGLE_STRIP );

		if ( item._type == MenuItem::TYPE_TITLE )
		{
			glColor4f( 0.3f,0.3f,0.3f, 0.8f );	glVertex2f( 1, 0 );			glVertex2f( _w, 0 );
			glColor4f( 0.4f,0.4f,0.4f, 0.8f );	glVertex2f( 1, item._h ); 	glVertex2f( _w, item._h );
		}
		else
		{
			if ( item._selected && i == _lbutt_down_sel_item )
			{
				glColor4f( 0.7f,0.7f,0.7f, 0.8f );	glVertex2f( 1, 0 );			glVertex2f( _w, 0 );
				glColor4f( 0.7f,0.7f,0.7f, 0.8f );	glVertex2f( 1, item._h ); 	glVertex2f( _w, item._h );
			}
			else
			{
				glColor4f( 0.8f,0.8f,0.8f, 0.8f );	glVertex2f( 1, 0 );			glVertex2f( _w, 0 );
				glColor4f( 0.9f,0.9f,0.9f, 0.8f );	glVertex2f( 1, item._h ); 	glVertex2f( _w, item._h );
			}
		}
		glEnd();

		if ( item._type == MenuItem::TYPE_CHECK ||
			 item._type == MenuItem::TYPE_TOGGLE_ITEM ||
			 item._type == MenuItem::TYPE_RADIOLIST_ITEM )
		{
			int ox = 4;
			int oy = (item._h - 8) / 2;
			glColor3f( 0, 0, 0 );

			glBegin( GL_LINE_LOOP );
				glVertex2f( ox, oy );		glVertex2f( ox+8, oy );
				glVertex2f( ox+8, oy+8 );	glVertex2f( ox, oy+8 );
			glEnd();

			if ( item.GetCheck() )
			{
				glBegin( GL_QUADS );
					glVertex2f( ox+2, oy+2 );			glVertex2f( ox+8-2+1, oy+2 );
					glVertex2f( ox+8-2+1, oy+8-2+1 );	glVertex2f( ox+2, oy+8-2+1 );
				glEnd();
			}
		}

		if ( item._type == MenuItem::TYPE_TITLE )
			glColor4f( 0.05f, 0.05f, 0.05f, 0.8f );
		else
			glColor4f( 0.4f, 0.4f, 0.4f, 0.8f );

		glBegin( GL_LINE_STRIP );
			glVertex2f( 0, item._h );
			glVertex2f( 0, 0 );
			glVertex2f( _w, 0 );
			glVertex2f( _w, item._h );
		glEnd();

		//---------------------------------------
		FONT_DrawBegin();

		glPushMatrix();
			glTranslatef( X1_MARGIN + CHECK_WIDTH + CHECK_X_MARGIN, Y1_MARGIN, 0 );
			if ( item._type == MenuItem::TYPE_TITLE )
			{
				glColor3f( 0.9f, 0.9f, 0.9f );
				FONT_puts( item._name );
				glTranslatef( 1, 0, 0 );
			}
			else
			{
				if ( item._selected )
					glColor3f( 0, 0, 1 );
				else
					glColor3f( 0, 0, 0 );
			}
			FONT_puts( item._name );
		glPopMatrix();

		FONT_DrawEnd();
		//---------------------------------------

		y += item._h;
	}
	glLoadIdentity();
	glTranslatef( _x, y, 0 );
	glColor4f( 0.4f, 0.4f, 0.4f, 0.8f );
	glBegin( GL_LINES );
		glVertex2f( 0, 0 );
		glVertex2f( _w, 0 );
	glEnd();


	for (int i=0; i < _itemsp.size(); ++i)
	{
		const MenuItem	&item = *_itemsp[ i ];

		if ( item._type == MenuItem::TYPE_SUBMENU )
		{
			item._submenup->redrawSub();
		}
	}
}

//==================================================================
void Menu::redraw()
{
	if NOT( _visible )
		return;

	glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_TEXTURE_BIT );
	glDisable( GL_DEPTH_TEST );
	glDisable( GL_TEXTURE_2D );
	begin_2D( NULL, NULL );

		redrawSub();

	end_2D();
	glPopAttrib();
}

//==================================================================
int Menu::find_item( int px, int py ) const
{
int		item_x, item_y;
int		item_w;

	item_x = _x;
	item_y = _y;
	item_w = _w;

	for (int i=0; i < _itemsp.size(); ++i)
	{
		const MenuItem	&item = *_itemsp[i];
		if ( !(item._type == MenuItem::TYPE_TITLE) && !(item._type == MenuItem::TYPE_EMPTY) )
		{
			if ( px >= item_x && px < item_x+item_w &&
				py >= item_y && py < item_y+item._h )
				return i;
		}
		item_y += item._h;
	}
	return PERROR;
}

//==================================================================
void Menu::handleMove( int x, int y, int w, int h )
{
	bool	elem_changed = false;

	int	pointed_item = find_item( x, y );

	_cur_sel_item = pointed_item;
	for (int i=0; i < _itemsp.size(); ++i)
	{
		if ( i != pointed_item )
		{
			if ( _itemsp[ i ]->_selected != false )
			{
				elem_changed = true;
				_itemsp[ i ]->_selected = false;
			}
		}
		else
		{
			if ( _itemsp[ i ]->_selected != true )
			{
				elem_changed = true;
				_itemsp[ i ]->_selected = true;
			}
		}
	}

	if ( elem_changed )
		invalidate();
}

//==================================================================
bool Menu::isPointInside( int x, int y ) const
{
	return (x >= _x && y >= _y && x < (_x+_w) && y < (_y+_h));
}

//==================================================================
void Menu::handleDragging( int x, int y )
{
	int	old_x = _x;
	int	old_y = _y;

	if ( x < _x )
		_x = x;
	else
	if ( x > _x+_w )
		_x = x-_w;

	if ( y < _y )
		_y = y;
	else
	if ( y > _y+_h )
		_y = y-_h;

	if ( old_x != _x || old_y != _y )
		invalidate();
}

//==================================================================
int	Menu::EventFilter_s( void *userdatap, WindowEvent *eventp )
{
	return ((Menu *)userdatap)->EventFilter( eventp, NULL );
}

//==================================================================
int	Menu::EventFilter( WindowEvent *eventp, Menu *parent_menup )	// WindowEvent::Type 
{
int		x, y;
//RECT	rc;
int		mouse_x;
int		mouse_y;

	//if ( !_visible || !_active )
	//	return 0;

	if ( _activity_childp )
		return _activity_childp->EventFilter( eventp, this );

	/*
	for (int i=0; i < _itemsp.size(); ++i)
	{
		if ( _itemsp[i]->_type == MenuItem::TYPE_SUBMENU )
			if ( _itemsp[i]->_submenup->mnu_mswin_eventfilter( hWnd, message, wParam, lParam ) )
				return _itemsp[i]->_submenup;
	}
	*/

	switch ( eventp->GetType() ) 
	{
	case WindowEvent::ETYPE_MOUSEMOVE:
		if ( _visible && _active )
		{
			x = eventp->mouse_x;
			y = eventp->mouse_y;

			if ( _is_popup )
			{
				handleDragging( x, y );

				if ( parent_menup )
				{
					// sets the parent relative position according to the new mouse position
					parent_menup->SetPos( x + parent_menup->_last_mouse_offset_x,
											   y + parent_menup->_last_mouse_offset_y );
				}

			}

			//GetClientRect( hWnd, &rc );
			handleMove( x, y, eventp->win_w, eventp->win_h );

			if ( isPointInside( x, y ) )
			{
				return 1;//this;
			}
		}
		break;

	case WindowEvent::ETYPE_RBUTTONDOWN:
		mouse_x = eventp->mouse_x;
		mouse_y = eventp->mouse_y;
		if ( _is_popup )
		{
			if ( IsShowing() )
			{
				if ( parent_menup )
				{
					// tell the parent that child is gone
					parent_menup->_activity_childp = NULL;

					// sets the parent relative position according to the new mouse position
					parent_menup->SetPos( mouse_x + parent_menup->_last_mouse_offset_x,
												mouse_y + parent_menup->_last_mouse_offset_y );
				}

				PASSERT( _activity_childp == NULL );
				_activity_childp = NULL;	// should already be null

				Show( false );

				_last_mouse_offset_x = _x - mouse_x;
				_last_mouse_offset_y = _y - mouse_y;
			}
			else
			{
				PASSERT( parent_menup == NULL );
				SetPos( mouse_x + _last_mouse_offset_x,
							 mouse_y + _last_mouse_offset_y );

				Show( true );
			}
		}
		break;

	case WindowEvent::ETYPE_LBUTTONDOWN:
		if ( _visible && _active )
		{
			x = eventp->mouse_x;
			y = eventp->mouse_y;
			//SetCapture( hWnd );

			if ( _cur_sel_item >= 0 )
			{
				_lbutt_down_sel_item = _cur_sel_item;
				return 1;
			}
			else
			if ( isPointInside( x, y ) )
			{
				return 1;
			}
		}
		break;

	case WindowEvent::ETYPE_LBUTTONUP:
		if ( _visible && _active )
		{
			x = eventp->mouse_x;
			y = eventp->mouse_y;
			//ReleaseCapture();

			if ( _cur_sel_item >= 0 &&
				_lbutt_down_sel_item == _cur_sel_item )
			{
				MenuItem	&item = *_itemsp[ _cur_sel_item ];
				if ( item._type == MenuItem::TYPE_SUBMENU )
				{
					item._submenup->SetPos( x + item._submenup->_last_mouse_offset_x,
										   y + item._submenup->_last_mouse_offset_y );

					item._submenup->Show( true );

					_activity_childp = item._submenup;
					_last_mouse_offset_x = _x - x;
					_last_mouse_offset_y = _y - y;

					_lbutt_down_sel_item = -1;

					if ( _callback )
						_callback( _callback_userdatap, this, item._userdatap );
				}
				else
				if ( item._type == MenuItem::TYPE_RADIOLIST_ITEM )
				{
					item.SetCheck( true );

					invalidate();
					_lbutt_down_sel_item = -1;

					if ( _callback )
						_callback( _callback_userdatap, this, item._radiolistp->_userdatap );
				}
				else
				if ( item._type == MenuItem::TYPE_TOGGLE_ITEM )
				{
					item.Toggle();
					invalidate();
					_lbutt_down_sel_item = -1;

					if ( _callback )
						_callback( _callback_userdatap, this, item._userdatap );
				}
				else
				{
					_lbutt_down_sel_item = -1;

					if ( _callback )
						_callback( _callback_userdatap, this, item._userdatap );
				}
				

				return 1;	// this
			}
			else
			if ( isPointInside( x, y ) )
			{
				return 1;	// this
			}
		}
		break;

	case WindowEvent::ETYPE_PAINT:
		redraw();
		break;
	}

	return 0;
}

//==================================================================
void Menu::BeginRadioList( int *userdatap, int from_val )
{
	PASSERT( userdatap != NULL );

	int	max_radio = 65536;	// fairly large value.. to avoid some asserts at build time

	_RadioListMaker.Reset( new RadioList( userdatap, from_val, _itemsp.size(), max_radio ) );
}

//==================================================================
void Menu::AddRadioItem( const TCHAR *namep )
{
	addItem( _RadioListMaker._radiolistp, namep );
	
	if ( _RadioListMaker.ItemMatchesCurVal() )
		ItemSetCheck( _RadioListMaker._radiolistp->_userdatap, true );
	
	_RadioListMaker._radiolistp->AddRef();
	_RadioListMaker.NextVal();
}

//==================================================================
void Menu::EndRadioList()
{
	_RadioListMaker._radiolistp->_n = _RadioListMaker._cur_val - _RadioListMaker._radiolistp->_from_val;
	_RadioListMaker.End();
}

/*
//==================================================================
bool Menu::GetClickedItem( u_int *item_idp )
{
	if ( item_idp )
		*item_idp = 0xffffffff;

	if ( userdatapp )
		*userdatapp = NULL;

	if ( _report_clicked_item < 0 )
		return false;

	MenuItem	*ip = _itemsp[ _report_clicked_item ];

	_report_clicked_item = -1;

	if ( item_idp )
		*item_idp = item._id;

	return true;
}
*/
